# -*- encoding: utf-8 -*-
"""
File Name: load_problems_from_zabbix
Description:
Author : 'lirui'
date: 2/6/2024
Contact: marjey_lee@163.com
Change Activity:
2/6/2024:
"""
import time
import ll
from modules.blk.cmdb.cmdb_service import CMDBService
from modules.zabbix_utils.utils.zabbix_client import ZabbixClient
from projects.monitoring.common.do.alarm import Alarm
from projects.monitoring.internet_zabbix_monitoring.config.config import INTERNET_ZABBIX_INFO

ll.get_logger().warning('Deprecated module, please use the new module in the same directory.')


class LoadProblemsFromZabbix:
    def __init__(self):
        pass

    @staticmethod
    def _load_cmdb_container_info():
        data = CMDBService().select('zabbix_docker_info')
        return data['data']['info']

    def load_problems(self):
        """
        load problems from zabbix server
        Returns:

        """
        ll.get_logger().info('Start to load problems from zabbix server.')
        problems_lst = []
        problems_lst = self._load_one_server_problem(problems_lst)
        ll.get_logger().info(
            f'Load problems from zabbix server finished, total problems count {len(problems_lst)}.'
        )
        return self._format_alarm(problems_lst)

    @staticmethod
    def _get_severity(severity_index):
        """
        """
        if str(severity_index) in ['0', '1', '2']:
            return 'remind'
        if str(severity_index) in ['3']:
            return 'warning'
        if str(severity_index) in ['4', '5']:
            return 'fatal'
        ll.get_logger().warning(f'Unknown severity_index: {severity_index}')

    @staticmethod
    def _format_alarm(problems_lst):
        """

        Args:
            problems_lst:

        Returns:

        """
        alarm_lst = []
        for p in problems_lst:
            alarm = Alarm(
                timestamp=int(p['clock']),
                ip=p['host_name'],
                hostname=p['host_name'],
                severity=LoadProblemsFromZabbix._get_severity(p['severity']),
                alarm_type='alarm',  # 'alarm,recovery'
                alarm_info=p['name'],
                note=None,
                recovery=False,
                recovery_time=None,
                manager_ip=p['zabbix_ip'],
                manager_port=p['zabbix_port'],
                alarm_source='zabbix'
            )
            alarm_lst.append(alarm.to_json())
        return alarm_lst

    def _load_one_server_problem(
            self,
            problems_lst
    ):
        """
        load one server problems
        Args:
            problems_lst:

        Returns:

        """
        try:
            client = ZabbixClient(
                ip=INTERNET_ZABBIX_INFO['ip'],
                port=INTERNET_ZABBIX_INFO['port'],
                username=INTERNET_ZABBIX_INFO['username'],
                password=INTERNET_ZABBIX_INFO['password']
            )
            problems = self._load_problem_hosts(client)
            problems_lst.extend(problems)
            return problems_lst
        except Exception as e:
            ll.get_logger().error(f"Load problem from internet zabbix server: {e}.")
            p = {'clock': str(int(time.time())),
                 'name': f"Can not connect to internet zabbix server ",
                 'acknowledged': '0',
                 'severity': '3',
                 'zabbix_ip': INTERNET_ZABBIX_INFO['ip'],
                 'zabbix_port': INTERNET_ZABBIX_INFO['port'],
                 'host_name': INTERNET_ZABBIX_INFO['ip'],
                 }
            problems_lst.append(p)
            return problems_lst

    @staticmethod
    def _load_problem_hosts(client: ZabbixClient):
        t = client.get_template('problems', 'hosts_with_problems')
        hosts = client.fetch(t)
        if len(hosts) == 0:
            return []
        problem_res = {}
        for host in hosts:
            t = client.get_template('problems', 'get')
            t['params']['hostids'] = host['hostid']
            problems = client.fetch(t)
            problems = LoadProblemsFromZabbix._filter_recovered_problems(problems)
            for problem in problems:
                problem['zabbix_ip'] = client.ip
                problem['zabbix_port'] = client.port
                problem['hostid'] = host['hostid']
                problem['host_name'] = host['name']
                problem_res[problem['name']] = problem
        return LoadProblemsFromZabbix.problems_more_than_fifth(problem_res)

    @staticmethod
    def _filter_recovered_problems(problems):
        """

        Returns:

        """
        ps = []
        for p in problems:
            if p['r_eventid'] == '0':
                ps.append(p)
        return ps

    @staticmethod
    def problems_more_than_fifth(problem_res):
        """

        Args:
            problem_res:

        Returns:

        """
        global TOTAL_ALARM_NUMBER
        keys = []
        for k, p in problem_res.items():
            k = p['name']
            keys.append(k)
        for k in keys:
            if k not in TOTAL_ALARM_NUMBER:
                TOTAL_ALARM_NUMBER[k] = 1
                continue
            TOTAL_ALARM_NUMBER[k] = TOTAL_ALARM_NUMBER[k] + 1
        res = []
        del_keys = []
        for k, n in TOTAL_ALARM_NUMBER.items():
            if k not in keys:
                del_keys.append(k)
                continue
            if n > 5:
                res.append(problem_res[k])
        for k in del_keys:
            TOTAL_ALARM_NUMBER.pop(k)
        return res


TOTAL_ALARM_NUMBER = {}
